#include "StackApp.h"

Stack initStack(int n)
{
    Stack stack;
    stack = malloc(sizeof(*stack));
    if (stack == NULL)
    {
        printf("malloc error\n");
        exit(EXIT_FAILURE);
    }
    stack->n = n;
    stack->i = -1;

    stack->_stack = malloc(n * sizeof(*(stack->_stack)));
    if (stack->_stack == NULL)
    {
        printf("malloc error\n");
        exit(EXIT_FAILURE);
    }
    return stack;
}
BOOL push(Stack S, ElementType x)
{
    if (S == NULL || S->i == S->n)
    {
        return FALSE;
    }

    S->_stack[++(S->i)] = x;
    return TRUE;
}
BOOL pop(Stack S, ElementType *x)
{
    if (S == NULL || S->i == -1 || x == NULL)
    {
        return FALSE;
    }
    *x = S->_stack[(S->i)--];
    return TRUE;
}

void releaseStack(Stack S)
{
    if (S == NULL)
    {
        return;
    }
    free(S->_stack);
    free(S);
}

BOOL callExpr(char *expr, int *result)
{
    if (expr == NULL || result == NULL)
    {
        return FALSE;
    }
    BOOL ret = FALSE;
    Stack s = NULL;
    int tnum, a, b;
    char *ptr = expr;

    s = initStack(100);
    if (s == NULL)
        goto _exit;

    while (*ptr != '\0')
    {
        if (*ptr == ' ')
        {
            ;
        }
        else if (isdigit(*ptr))
        {
            tnum = 0;
            while (*ptr >= '0' && *ptr <= '9')
            {
                tnum = tnum * 10 + *ptr - '0';
                ptr++;
            }
            push(s, tnum);
        }
        else
        {

            if (!pop(s, &a))
                goto _exit;
            else if (!pop(s, &b))
                goto _exit;

            switch (*ptr)
            {
            case '+':
                if (!push(s, b + a))
                    goto _exit;

                break;
            case '-':
                if (!push(s, b - a))
                    goto _exit;
                break;
            case '*':
                if (!push(s, b * a))
                    goto _exit;
                break;
            case '/':
                if (!push(s, b / a))
                    goto _exit;
                break;
            default:
                goto _exit;
            }
        }

        ptr++;
    }

    if (!pop(s, result))
        goto _exit;
    else if (!isEmpty(s))
        goto _exit;
    ret = TRUE;
_exit:

    releaseStack(s);
    return ret;
}

int main()
{
    char *str = "46 5 120 37 - * +";
    int result = 0;
    if (callExpr(str, &result))
    {
        printf("result: %d\n", result);
    }
    else
    {
        printf("format error\n");
    }
}